package cn.tnar.parkservice.controller.order;


import cn.tnar.parkservice.config.Constant;
import cn.tnar.parkservice.config.ExportConstant;
import cn.tnar.parkservice.exception.CustomException;
import cn.tnar.parkservice.model.entity.*;
import cn.tnar.parkservice.model.request.ExportRefundRequest;
import cn.tnar.parkservice.model.request.OfflineRefundReq;
import cn.tnar.parkservice.model.request.OrderRefundRequest;
import cn.tnar.parkservice.model.request.TradeRefundRequset;
import cn.tnar.parkservice.model.response.TradeRefundResponse;
import cn.tnar.parkservice.service.*;
import cn.tnar.parkservice.util.DateUtils;
import cn.tnar.parkservice.util.DtoUtil;
import cn.tnar.parkservice.util.ExcelUtil;
import cn.tnar.parkservice.util.common.ResultCode;
import cn.tnar.parkservice.util.common.ResultJson;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;

/**
 * 退款记录
 *
 * @author Tiyer.Tao
 * @since 2018-09-18
 */
@Api(tags = "退款记录(张鑫) : t_trade_refund - Controller")
@RestController
@RequestMapping("service/tTradeRefund")
@Slf4j
public class TTradeRefundController {
    //时间格式
    public static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    //金额保留小数格式
    public static final DecimalFormat df = new DecimalFormat("#.00");

    @Autowired
    @Qualifier("tTradeRefundServiceImpl")
    private ITTradeRefundService it_trade_refundService;

    @Autowired
    @Qualifier("tCarMemberamountinfoServiceImpl")
    private ITCarMemberamountinfoService itCarMemberamountinfoService;

    @Autowired
    @Qualifier("tAcctRefundRecordServiceImpl")
    private ITAcctRefundRecordService itAcctRefundRecordService;


    @Autowired
    @Qualifier("tSysSnogeneralServiceImpl")
    private ITSysSnogeneralService itSysSnogeneralService;

    @Autowired
    @Qualifier("tParkGroupMemberinfoServiceImpl")
    private ITParkGroupMemberinfoService itParkGroupMemberinfoService;

    @Autowired
    @Qualifier("tParkGroupSeatinfoServiceImpl")
    private ITParkGroupSeatinfoService itParkGroupSeatinfoService;


    private ResultJson resultJson = new ResultJson();

    @ApiOperation(value = "根据订单号查询退款记录 - t_trade_refund")
    @PostMapping(value = "queryById")
    public ResultJson queryById(@RequestParam("orderNumber") String orderNumber) {
        QueryWrapper<TTradeRefund> ew = new QueryWrapper<>();
        ew.eq("order_number", orderNumber);
        TTradeRefund tradeRefund = it_trade_refundService.getOne(ew);
        return resultJson.setCode(ResultCode.SUCCESS).setMsg(ResultCode.SUCCESS_MSG).setData(tradeRefund);
    }


    @ApiOperation(value = "退款记录页面查询 - t_trade_refund")
    @PostMapping(value = "queryPage")
    public ResultJson queryPage(@RequestBody String json) {
        TradeRefundRequset tradeRefundRequset = JSON.parseObject(json, TradeRefundRequset.class);
        long cust_id = tradeRefundRequset.getCustId();
        int refund_state = tradeRefundRequset.getRefundState() > 0 ? tradeRefundRequset.getRefundState() : 1;
        Page<TradeRefundResponse> list = it_trade_refundService.getRefundByPage(tradeRefundRequset);
        return resultJson.setCode(ResultCode.SUCCESS).setMsg(ResultCode.SUCCESS_MSG).setData(list);
    }

    @ApiOperation(value = "退款记录状态审核 - t_trade_refund")
    @PostMapping(value = "auditRefund")
    @Transactional(rollbackFor = Exception.class)
    public ResultJson auditRefund(@RequestBody TTradeRefund tradeRefund) {
        boolean result = false;
        if (tradeRefund.getId() > 0) {
            result = it_trade_refundService.updateAuditRefund(tradeRefund);
        }
        if (result) {
            return resultJson.setCode(ResultCode.SUCCESS).setMsg(ResultCode.SUCCESS_MSG);
        } else {
            return resultJson.setCode(ResultCode.FAIL).setMsg(ResultCode.FAIL_MSG);
        }
    }


    @ApiOperation(value = "新增退款记录 更新订单状态 - t_trade_refund")
    @PostMapping(value = "insertAndUpdateRefund")
    @Transactional(rollbackFor = Exception.class)
    public ResultJson insertAndUpdateRefund(@RequestBody String json) {
        OrderRefundRequest orderRefund = JSON.parseObject(json, OrderRefundRequest.class);
        boolean result = false;
        TTradeRefund tradeRefund = DtoUtil.convertObject(orderRefund, TTradeRefund.class);
        tradeRefund.setRefundtime(Long.valueOf(new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())));
        result = it_trade_refundService.save(tradeRefund);
        if (result) {
            //1待确认2确认3待支付4支付成功5取消6待退款7退款成功8失败9待发货10已发货11待收货12已收货13交易完成21已超时
//            int state = 6;
            result = it_trade_refundService.updateTradeCommodityState(tradeRefund.getOrderNumber(), tradeRefund.getRefundamount());
        }
        if (result) {
            return resultJson.setCode(ResultCode.SUCCESS).setMsg(ResultCode.SUCCESS_MSG);
        } else {
            return resultJson.setCode(ResultCode.FAIL).setMsg(ResultCode.FAIL_MSG);
        }
    }

    @ApiOperation(value = "导出-退款记录", notes = "导出根据查询条件查询出的退款记录")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "parkCode", value = "停车场编码", required = false, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "carNo", value = "车牌号", required = false, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "orderNumber", value = "订单号", required = false, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "refundState", value = "审核状态", required = false, dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "startDate", value = "开始时间", required = false, dataType = "Long", paramType = "query"),
            @ApiImplicitParam(name = "endDate", value = "结束时间", required = false, dataType = "Long", paramType = "query")
    })
    @RequestMapping(value = "/exportRefund", method = {RequestMethod.POST, RequestMethod.GET})
    public void exportRefund(@RequestBody String json, HttpServletResponse response) throws Exception {
        ExportRefundRequest refundRequest = JSON.parseObject(json, ExportRefundRequest.class);
        String fileName = "退款记录" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")) + ".xls";
        String sheetName = "退款记录";
        //回填内容
        String[][] contents = null;
        /**
         * 功能已完成【修改sql即可】
         */
        List<TradeRefundResponse> list = it_trade_refundService.getRefundList(refundRequest.getParkCode(),
                refundRequest.getCarNo(),
                refundRequest.getOrderNumber(),
                refundRequest.getRefundState(),
                refundRequest.getStartTime(),
                refundRequest.getEndTime());
        if (!list.isEmpty()) {
            contents = new String[list.size()][8];
            for (int i = 0; i < list.size(); i++) {
                contents[i][0] = i + 1 + "";//序号
                contents[i][1] = list.get(i).getOrderNumber();//订单号
                contents[i][2] = list.get(i).getName();//停车场名称
                contents[i][3] = list.get(i).getCarNo();//车牌号
                contents[i][4] = list.get(i).getSendtime() != 0 ? sdf.format(list.get(i).getSendtime()) : "";//入场时间
                contents[i][5] = list.get(i).getRecvtime() != 0 ? sdf.format(list.get(i).getSendtime()) : "";//出场时间
                contents[i][6] = df.format(list.get(i).getRefundAmount());//退款金额
                contents[i][7] = list.get(i).getOperName();//发起人
            }
        }
        ExcelUtil.export(fileName, sheetName, ExportConstant.Refund_title, contents, response);
    }


    /**
     * 线下退款
     *
     * @param json
     * @return
     */
    @ApiOperation("线下退款")
    @PostMapping("/offlineRefund")
    public ResultJson OfflineRefund(@RequestBody String json) {
        try {
            OfflineRefundReq offlineRefundReq = JSON.parseObject(json, OfflineRefundReq.class);
            Integer startDate = offlineRefundReq.getStartDate(); //开始日期
            Integer endDate = offlineRefundReq.getEndDate(); //截止日期
            BigDecimal refoundAmt = offlineRefundReq.getRefoundAmt(); //退款金额
            Long custId = offlineRefundReq.getCustId(); //停车场custId
            String parkCode = offlineRefundReq.getParkCode(); //停车场parkCode
            Long feesRoleId = offlineRefundReq.getFeesRoleId(); //套餐id
            String feesRoleName = offlineRefundReq.getFeesRoleName(); //套擦名称
            Long now = Long.valueOf(DateUtils.getTime()); //当前时间
            BigDecimal monthValue = offlineRefundReq.getMonthValue(); //套餐金额
            Long operId = offlineRefundReq.getOperId();//操作员id
            String regionCode = offlineRefundReq.getRegionCode();//区域编号
            Long memberId = offlineRefundReq.getMemberId();//会员id
            Long seatId = offlineRefundReq.getSeatId(); //车位id
            String carId = offlineRefundReq.getCarId(); //车牌号
            Long customer_custId = offlineRefundReq.getCustomer_custId(); //客户号custId
            String phone = offlineRefundReq.getPhone();//手机号

            //插入会员交费变更记录表
            TCarMemberamountinfo tCarMemberamountinfo = new TCarMemberamountinfo();
            tCarMemberamountinfo.setId(getTableNo(3));
            tCarMemberamountinfo.setNodeId(1);
            tCarMemberamountinfo.setCustId(custId); //停车场的custId
            tCarMemberamountinfo.setParkCode(parkCode); //停车场的parkCode
            tCarMemberamountinfo.setAmountType(6); //6 线下退款
            tCarMemberamountinfo.setFeesRoleid(feesRoleId);//套餐id
            tCarMemberamountinfo.setRoleName(feesRoleName); //套餐名称
            tCarMemberamountinfo.setMonthValue(monthValue); //套餐金额
            tCarMemberamountinfo.setUpTime(now);
            tCarMemberamountinfo.setAmountNum(refoundAmt); //前端传入
            tCarMemberamountinfo.setStartDate(startDate); //前端传入会员开始日期
            tCarMemberamountinfo.setEndDate(endDate); //前端传入会员截止日期
            tCarMemberamountinfo.setOperId(operId); //前端传入，操作员客户号
            tCarMemberamountinfo.setRemark("长租车会员线下退款"); //描述
            tCarMemberamountinfo.setRegionCode(regionCode); // 区域编号
            tCarMemberamountinfo.setBuyOri(0); //0.云岗亭  1.app  2.微信
            tCarMemberamountinfo.setPayId("0");  //0
            tCarMemberamountinfo.setMemberId(memberId); //会员表id
            tCarMemberamountinfo.setSeatId(seatId);
            tCarMemberamountinfo.setCarId(carId);
            itCarMemberamountinfoService.save(tCarMemberamountinfo);

            //插入退款记录表
            TAcctRefundRecord tAcctRefundRecord = new TAcctRefundRecord();
            tAcctRefundRecord.setNodeId(1);
            tAcctRefundRecord.setCustId(customer_custId); //客户custId
            tAcctRefundRecord.setPhone(phone); //手机号，前端传入
            tAcctRefundRecord.setRefundAmt(refoundAmt);//退款金额
            tAcctRefundRecord.setRefundChannel(3); //1 微信  2 支付宝 3.云岗亭
            tAcctRefundRecord.setRefundRemark("长租车会员线下退款"); //退款原因
            tAcctRefundRecord.setRefundTime(now);  //退款申请时间
            tAcctRefundRecord.setRefundStatus(5); //审核状态
//            tAcctRefundRecord.setOperationalOperator(""); //运营审核操作员
//            tAcctRefundRecord.setFinancialOperator(""); //财务审核操作员
//            tAcctRefundRecord.setManagerOperator("");  //总经办审核员
//            tAcctRefundRecord.setOperationalChecktime(0L); //运营审核时间
//            tAcctRefundRecord.setFinancialChecktime(0L); //财务审核时间
//            tAcctRefundRecord.setManagerChecktime(0L); //总经办审核时间
            tAcctRefundRecord.setRemark(""); //描述
            tAcctRefundRecord.setRefuseRemark(""); //拒绝原因
            itAcctRefundRecordService.save(tAcctRefundRecord);

            //插入交易退款表
            TTradeRefund tTradeRefund = new TTradeRefund();
            tTradeRefund.setNodeId(1);
//            tTradeRefund.setObjectId(0L);
            tTradeRefund.setCustId(customer_custId);
            //获取订单号,暂定
            tTradeRefund.setOrderNumber("");
            tTradeRefund.setRefundamount(refoundAmt);
            tTradeRefund.setRefundtime(now);
            tTradeRefund.setRefundreason("长租车会员线下退款");//线下退款
            tTradeRefund.setRefundstate(3);
            tTradeRefund.setEndtime(now); //退款完成时间
            tTradeRefund.setOperId(operId); //操作员id
            tTradeRefund.setDescription(""); //失败原因描述
            tTradeRefund.setRemark(""); //描述
//            tTradeRefund.setFirstCheckId(0L);
//            tTradeRefund.setFirstCheckTime(0L);
//            tTradeRefund.setSecCheckId(0L);
//            tTradeRefund.setSecCheckTime(0L);
//            tTradeRefund.setThirdCheckId(0L);
//            tTradeRefund.setThirdCheckTime(0L);
            it_trade_refundService.save(tTradeRefund);

            //修改会员的到期时间
            TParkGroupMemberinfo tParkGroupMemberinfo = new TParkGroupMemberinfo();
            tParkGroupMemberinfo.setId(memberId);
            tParkGroupMemberinfo.setEndDate(endDate);
            itParkGroupMemberinfoService.updateById(tParkGroupMemberinfo);

            //修改车位信息表的到期时间
            TParkGroupSeatinfo tParkGroupSeatinfo = new TParkGroupSeatinfo();
            tParkGroupSeatinfo.setId(seatId);
            tParkGroupSeatinfo.setEndDate(endDate);
            itParkGroupSeatinfoService.updateById(tParkGroupSeatinfo);
            return new ResultJson().setCode(ResultCode.SUCCESS).setMsg(ResultCode.SUCCESS_MSG).setData(true);
        } catch (Exception e) {
            log.error("线下退款异常", e);
            return new ResultJson().setCode(ResultCode.FAIL).setMsg(ResultCode.FAIL_MSG).setData(null);
        }
    }


    private Long getTableNo(Integer num) {
        Long id = null;
        try {
            if (num == 1) {
                //  groupMemberinfoId
                id = itSysSnogeneralService.GetNextSno(500);
            }
            if (num == 2) {
                // groupCarinfoId
                id = itSysSnogeneralService.GetNextSno(501);
            }
            if (num == 3) {
                // memberamountinfoId
                id = itSysSnogeneralService.GetNextSno(53);
            }
            if (num == 4) {
                // operateLogId
                id = itSysSnogeneralService.GetNextSno(504);
            }

        } catch (Exception e) {
            log.error(Constant.ERROR_MSG_SNO, e);
            throw new CustomException(Constant.ERROR_MSG_SNO);
        }
        return id;
    }

}

